package props

import "gitee.com/night-tc/gobige/global"

/*
分流器接口
*/
type IPropsDirtySorter interface {
	// 标记脏数据
	FlagDirty(p IProp)
	//分流器类型
	GetSorterType() EDPSorterType
	// 列表获取回调
	HandlerAllList(consumeListFunc func(list []IProp) bool)
	// 成员遍历回调
	HandlerForEach(consumeFunc func(p IProp))
	//获取脏数据
	ListCount() int
	//弹出所有脏数据
	PopDirtyList() (result []IProp)
}

// 分流器类型
type EDPSorterType int8

const (
	//同步分流器
	EDPSorterTypeSync EDPSorterType = 1
	//保存分流器
	EDPSorterTypeSave EDPSorterType = 2
)

func NewPropsDirtySorter(sorter EDPSorterType) *PropsDirtySorter {
	result := new(PropsDirtySorter)
	result.dirtyProps = make([]IProp, 0, 20)
	result.sorterType = sorter
	return result
}

/*
属性脏分流器
*/

type PropsDirtySorter struct {
	// 标记脏的数据
	dirtyProps []IProp
	//分流器类型
	sorterType EDPSorterType
}

func (this *PropsDirtySorter) GetSorterType() EDPSorterType {
	return this.sorterType
}

// 标记脏数据
func (this *PropsDirtySorter) FlagDirty(p IProp) {
	switch this.sorterType {
	case EDPSorterTypeSync:
		{
			if p.GetField().IsSync {
				if !p.IsSyncDirty() {
					p.setSync(true)
					this.dirtyProps = append(this.dirtyProps, p)
				}
			}
		}
	case EDPSorterTypeSave:
		{
			if p.GetField().SaveSrv == global.GetCfgInst().GetDefType() {
				if !p.IsSaveDirty() {
					p.setSave(true)
					this.dirtyProps = append(this.dirtyProps, p)
				}
			}
		}
	}
}

func (this *PropsDirtySorter) ListCount() int {
	return len(this.dirtyProps)
}

// 成员遍历回调
func (this *PropsDirtySorter) HandlerForEach(consumeFunc func(p IProp)) {
	dirtyProps := this.PopDirtyList()
	for _, v := range dirtyProps {
		consumeFunc(v)
	}
}

// 列表获取回调
func (this *PropsDirtySorter) HandlerAllList(consumeListFunc func(list []IProp) bool) {
	dirtyProps := this.PopDirtyList()
	consumeListFunc(dirtyProps)
}

/*
弹出脏数据
这里需要注意，返回的切片与分流器里的是同一份数组，需要确保拿到这个切片后，
只做遍历，不做保留处理；
*/
func (this *PropsDirtySorter) PopDirtyList() (result []IProp) {
	if len(this.dirtyProps) == 0 {
		return this.dirtyProps
	}
	result = this.dirtyProps
	this.dirtyProps = this.dirtyProps[0:0]
	for _, p := range result {
		switch this.sorterType {
		case EDPSorterTypeSave:
			p.setSave(false)
		case EDPSorterTypeSync:
			p.setSync(false)
		}
	}
	return
}
